package math.geom2d;

import math.BSplineUtils;
import math.base.Point2d;
import math.base.Vector2d;
import math.geomUtils.CurveType;

/**
 * @author Saga
 *
 */
public class BezierCurve2d extends BoundedCurve2d {
    public BezierCurve2d(final Point2d[] _poles) {
        if (_poles.length < 1 || _poles.length > 25) {
            throw new ArithmeticException("");
        }

        this.ctrlPoles = _poles;
        this.rational = false;
        this.firstParam = 0.0;
        this.lastParam = 1.0;
        this.firstPt = _poles[0];
        this.lastPt = _poles[_poles.length - 1];
    }

    public BezierCurve2d(final Point2d[] _poles, final double[] _weights) {
        if (_poles.length < 1 || _poles.length > 25 || _poles.length != _weights.length) {
            throw new ArithmeticException("");
        }

        this.rational = BSplineUtils.isRational(_weights);
        if (this.rational) {
            this.weights = _weights;
        }

        this.ctrlPoles = _poles;
        this.firstParam = 0.0;
        this.lastParam = 1.0;
        this.firstPt = _poles[0];
        this.lastPt = _poles[_poles.length - 1];
    }

    @Override
    public CurveType getCurveType() {
        return CurveType.BEZIER_CURVE;
    }

    @Override
    public void reverse() {

    }

    @Override
    public Curve2d reversed() {
        return null;
    }

    @Override
    public boolean isPeriodic() {
        return false;
    }

    @Override
    public double getPeriod() {
        throw new ArithmeticException("");
    }

    public Point2d calcValue(final double _param) {
        if (this.rational) {
            return BSplineUtils.deCasteljau2d(this.ctrlPoles, _param);
        } else {
            return BSplineUtils.deCasteljauWithWeights2d(this.ctrlPoles, this.weights, _param);
        }
    }

    public Vector2d calcDerivative(final double _param) {
        return null;
    }

    public Vector2d calcDerivativeN(final double _param, final int _order) {
        return null;
    }

    public void calcValueAndDerivative1(final double _param, final Point2d _pt,
            final Vector2d _der1) {

    }

    public void calcValueAndDerivative2(final double _param, final Point2d _pt,
            final Vector2d _der1, final Vector2d _der2) {

    }

    public void calcValueAndDerivative3(final double _param, final Point2d _pt,
            final Vector2d _der1, final Vector2d _der2, final Vector2d _der3) {

    }

    private final Point2d[] ctrlPoles;
    private double[] weights;
    boolean rational;
}
